package com.cracker.websocket.server.controller;

import com.cracker.websocket.server.dao.UserDao;
import com.cracker.websocket.server.entity.UserEntity;
import com.cracker.websocket.server.event.SessionOfflineEvent;
import com.cracker.websocket.server.event.SessionOnlineEvent;
import com.cracker.websocket.server.service.BrokerService;
import com.cracker.websocket.server.service.SessionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

@Controller
@ServerEndpoint("/app")
@Slf4j
public class AppController {
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private UserEntity userEntity;
    private static UserDao userDao;
    private static SessionService sessionService;
    private static BrokerService brokerService;
    private static ApplicationContext applicationContext;

    @Autowired
    public void setWsService(SessionService sessionService) {
        AppController.sessionService = sessionService;
    }

    @Autowired
    public void setBrokerService(BrokerService brokerService) {
        AppController.brokerService = brokerService;
    }

    @Autowired
    public void setUserDao(UserDao userDao) {
        AppController.userDao = userDao;
    }

    @Autowired
    public void setApplicationContext(ApplicationContext applicationContext) {
        AppController.applicationContext = applicationContext;
    }

    @OnOpen
    public void onOpen(Session session) {
        // 参数校验
        String token = session.getRequestParameterMap().get("token").get(0);
        userEntity = userDao.getByToken(token);
        log.warn("登录用户: {}", userEntity.getId());
        session.getUserProperties().put("user", userEntity);
        applicationContext.publishEvent(new SessionOnlineEvent(this, session, userEntity));
    }

    @OnMessage
    public void onMessage(Session session, String message) throws IOException {
        sessionService.freshUser(session);
        if ("ping".equals(message)) {
            session.getBasicRemote().sendText("pong");
            return;
        }
        brokerService.handle(session, message);
    }

    @OnClose
    public void onClose(Session session) {
        log.warn("用户{} 退出", userEntity.getId());
        applicationContext.publishEvent(new SessionOfflineEvent(this, session, userEntity));
    }
}
